package com.yenroc.ho.多线程;

import java.util.concurrent.*;

/**
 * 带返回结果的线程,Future,CompletableFuture
 */
public class MyThread05 {

    public static void main(String[] args) throws Exception {
        // 1. Future
        ExecutorService executors = Executors.newFixedThreadPool(3);
        Future<String> myTaskThreadCallableFuture = executors.submit(new MyTaskThreadCallable());
        executors.submit(new My05Runnable());
        // 执行get 会阻塞线程，需要放到下面执行
        System.out.println(myTaskThreadCallableFuture.get(550L,TimeUnit.MILLISECONDS));

        executors.shutdown();


        // 2. CompletableFuture
        CompletableFuture<String> stringCompletableFuture = CompletableFuture.supplyAsync(() -> { // Supplier 接口 T get();
            System.out.println("CompletableFuture 执行逻辑。。。");
            try {
                Thread.sleep(500L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // int i = 1/0; // 进入exceptionally 打印CompletableFuture 执行逻辑异常，异常信息=[java.lang.ArithmeticException: / by zero]
            return "success";
        });
        stringCompletableFuture.thenAccept((result)->{// Consumer 接口 void accept(T t);
            System.out.printf("stringCompletableFuture 执行逻辑成功，返回结果=[%s] \n", result);
        });
        stringCompletableFuture.exceptionally(e->{// Function 接口 R apply(T t);
            System.out.printf("stringCompletableFuture 执行逻辑异常，异常信息=[%s] \n", e.getMessage());
            return null;
        });

        // anyOf()可以实现“任意个CompletableFuture只要一个成功”，allOf()可以实现“所有CompletableFuture都必须成功”，这些组合操作可以实现非常复杂的异步流程控制
        CompletableFuture<String> stringCompletableFuture2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(800L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "stringCompletableFuture2 success";
        });
        CompletableFuture<Object> objectCompletableFuture = CompletableFuture.anyOf(stringCompletableFuture, stringCompletableFuture2);
        objectCompletableFuture.thenAccept((result)->{// Consumer 接口 void accept(T t);
            System.out.printf("stringCompletableFuture,stringCompletableFuture2 执行逻辑成功，返回结果=[%s] \n", result);
        });

        // 主线程不能直接结束
        Thread.sleep(1000L);
    }

}

/**
 * 实现Runnable的没有办法获取返回值
 */
class My05Runnable implements Runnable {
    @Override
    public void run() {
        System.out.print(Thread.currentThread().getName() + "\tMyRunnable class is running..\n");
        try {
            Thread.sleep(500L);
        } catch (java.lang.InterruptedException e){
            e.printStackTrace();
        }
        System.out.print(Thread.currentThread().getName() + "\tMyRunnable class is end..\n");
    }
}

/**
 * 实现Callable的支持 获取返回值
 */
class MyTaskThreadCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        System.out.print(Thread.currentThread().getName() + "\tMyTaskThreadCallable class is running..\n");
        try {
            Thread.sleep(500L);
        } catch (java.lang.InterruptedException e){
            e.printStackTrace();
        }
        System.out.print(Thread.currentThread().getName() + "\tMyTaskThreadCallable class is end..\n");
        return "MyTaskThreadCallable run is success.";
    }
}